package services

import (
	"strconv"

	"github.com/mlogclub/simple/sqls"
	"github.com/mlogclub/simple/web/params"
	"gorm.io/gorm"

	"bbs-go/internal/consts"
	"bbs-go/internal/models"
	"bbs-go/internal/repositories"
)

var ChatFriendsService = newChatFriendsService()

func newChatFriendsService() *chatFriendsService {
	return &chatFriendsService{}
}

type chatFriendsService struct {
}

func (s *chatFriendsService) Get(id int64) *models.ChatFriends {
	return repositories.ChatFriendsRepository.Get(sqls.DB(), id)
}

func (s *chatFriendsService) Take(where ...interface{}) *models.ChatFriends {
	return repositories.ChatFriendsRepository.Take(sqls.DB(), where...)
}

func (s *chatFriendsService) Find(cnd *sqls.Cnd) []models.ChatFriends {
	return repositories.ChatFriendsRepository.Find(sqls.DB(), cnd)
}

func (s *chatFriendsService) FindPageByParams(params *params.QueryParams) (list []models.ChatFriends, paging *sqls.Paging) {
	return repositories.ChatFriendsRepository.FindPageByParams(sqls.DB(), params)
}

func (s *chatFriendsService) FindPageByCnd(cnd *sqls.Cnd) (list []models.ChatFriends, paging *sqls.Paging) {
	return repositories.ChatFriendsRepository.FindPageByCnd(sqls.DB(), cnd)
}

func (s *chatFriendsService) Create(t *models.ChatFriends) error {
	return repositories.ChatFriendsRepository.Create(sqls.DB(), t)
}

func (s *chatFriendsService) Update(t *models.ChatFriends) error {
	return repositories.ChatFriendsRepository.Update(sqls.DB(), t)
}

func (s *chatFriendsService) Updates(id int64, columns map[string]interface{}) error {
	return repositories.ChatFriendsRepository.Updates(sqls.DB(), id, columns)
}

func (s *chatFriendsService) UpdateColumn(id int64, name string, value interface{}) error {
	return repositories.ChatFriendsRepository.UpdateColumn(sqls.DB(), id, name, value)
}

func (s *chatFriendsService) GetChatFriendsByFriendId(userId, friendUserId int64) (models.ChatFriends, error) {
	chatFriends := models.ChatFriends{}
	err := sqls.DB().Model(&models.ChatFriends{}).Where("user_id = ? AND friend_id = ?", userId, friendUserId).First(&chatFriends).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return models.ChatFriends{}, err
	}
	return chatFriends, nil
}

func (s *chatFriendsService) DeleteFriend(userId, friendId int64) error {
	tx := sqls.DB().Begin()
	err := tx.Delete(&models.ChatFriends{}, "user_id = ? and friend_id = ?", userId, friendId).Error
	if err != nil {
		tx.Rollback()
		return err
	}
	err = tx.Delete(&models.ChatFriends{}, "user_id = ? and friend_id = ?", friendId, userId).Error
	if err != nil {
		tx.Rollback()
		return err
	}
	err = tx.Commit().Error
	if err != nil {
		tx.Rollback()
		return err
	}
	return nil
}

func (s *chatFriendsService) GetChatFriendsList(page *sqls.Paging, userId int64) (models.ChatFirendListResponse, error) {
	limit := page.Limit
	offset := page.Limit * (page.Page - 1)
	if limit == 0 {
		limit = 10
	}
	db := sqls.DB()
	querySql := `select cf.*,
	tu.nickname as user_nickname,tu.avatar as user_avatar,tu.email as user_email,tu.username as username
	from chat_friends cf 
	left join t_user tu on cf.friend_id  = tu.id 
	where 1=1 and cf.deleted_at is null`
	whereSql := ""
	whereVars := []interface{}{}

	whereSql += " and cf.status = ? "
	whereVars = append(whereVars, consts.ChatFriendStatus_1)

	whereSql += " and cf.user_id = ? "
	whereVars = append(whereVars, userId)

	countSql := `select count(1)
	from chat_friends cf 
	where 1=1 `

	var total int64
	err := db.Raw(countSql+whereSql, whereVars...).Scan(&total).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return models.ChatFirendListResponse{}, err
	}

	list := []models.ChatFriendResponse{}
	orderBySql := " order by cf.id desc LIMIT " + strconv.Itoa(limit) + " OFFSET " + strconv.Itoa(offset)
	err = db.Raw(querySql+whereSql+orderBySql, whereVars...).Find(&list).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return models.ChatFirendListResponse{}, err
	}

	return models.ChatFirendListResponse{
		List: list,
		Paging: &sqls.Paging{
			Page:  page.Page,
			Limit: page.Limit,
			Total: total,
		},
	}, nil
}

func (s *chatFriendsService) GetChatFriendsInfoByFriendId(userId, friendUserId int64) (models.ChatFriendInfo, error) {
	chatFriends := models.ChatFriendInfo{}

	querySql := `select cf.user_id,cf.friend_id,tu.nickname as friend_nickname from chat_friends cf 
left join t_user tu on cf.friend_id = tu.id  
where cf.deleted_at is NULL `

	whereSql := ""
	whereVars := []interface{}{}

	whereSql += " and cf.user_id = ? and cf.friend_id = ? "
	whereVars = append(whereVars, userId)
	whereVars = append(whereVars, friendUserId)
	orderBySql := " order by cf.id desc "
	err := sqls.DB().Raw(querySql+whereSql+orderBySql, whereVars...).First(&chatFriends).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return models.ChatFriendInfo{}, err
	}
	return chatFriends, nil
}
